#ifndef _BG_ELEMENT_H_
#define _BG_ELEMENT_H_

#include "math/vec2.h"
#include <string>
namespace LuaPlus
{
	class LuaObject;	
}
namespace script
{
	class WriteLua;
}


namespace background
{
class BGScene;
class	BGElement
{
public:
	enum					ELEMENT_TYPE
	{
		ELEMENT_PARTSYS,
		ELEMENT_DECAL,
		ELEMENT_UVDECAL,
		ELEMENT_BOBDECAL,
		ELEMENT_ROTDECAL,
		ELEMENT_GLOWDECAL,
		ELEMENT_PANDECAL,
		ELEMENT_BIPED,
		ELEMENT_C,
		ELEMENT_CUSTOM,
		ELEMENT_UNKNOWN
	};
	
							BGElement(BGScene*	pScene);
	virtual					~BGElement();
	virtual void			Render(const math::Vec2& Offset, float	Scale) = 0;
	virtual void			RenderDebug(const math::Vec2& Offset, float	Scale);
	virtual void			Tick(float dt);
			bool			IsInside(const math::Vec2& Pos, const math::Vec2& Offset);
			bool			InsideRegion(const math::Vec2& From, const math::Vec2& To);
	virtual void			Load(LuaPlus::LuaObject& Obj);
	virtual void			Save(script::WriteLua* pWL);

	virtual void			RecalcBoundingBox() ;
	std::string				GetType() const { if (m_Type < ELEMENT_C) {return MapTypeToString(m_Type);} return m_Name; };		// override this to create it
	static	BGElement*		LoadElement(BGScene*	pScene, LuaPlus::LuaObject&	Obj);
	static bool				BySortFunc( BGElement * elem1, BGElement* elem2 ) { 	return elem1->GetSort() < elem2->GetSort(); };

	void					Pan(float dt);
	void					Rotate(float dt);

	virtual void			FlushImages() {};	// drop resources
	
	void					ResetElement(); // reset element to initial settings
	virtual void			OnElementReset() {};

	// accessors
	math::Vec2				GetScreenPos(const math::Vec2& Offset, float Scale);
	const math::Vec2&		GetPos() const { return m_Pos; };
	void					SetPos(const math::Vec2& P) { m_Pos = m_BasePos = P; };
	const math::Vec2&		GetSize() const { return m_Size; };
	void					SetSize(const math::Vec2& P) { m_Size = P; };
	const math::Vec2&		GetDir() const { return m_Dir; };
	void					SetDir(const math::Vec2& P) { m_Dir = P; };
	float					GetRotation() const { return m_Rotation; };
	void					SetRotation(float f) { m_Rotation = f; RecalcBoundingBox(); };
	float					GetSort() const { return m_Sort; };
	void					SetSort(float f) { m_Sort = f; };
	const math::Vec2&		GetClip() { return m_ClipSize; };

	bool					IsVisible(const math::Vec2&	Offset, float	Scale);

	virtual bool			MatchSubStr(const std::string& SubStr) { return false; };
	bool					IsActive() const { return m_IsActive; }
	void					SetActive(bool b){ m_IsActive = b; }
	virtual const char*		GetName()  { return ""; };
	ELEMENT_TYPE			GetElementType() const { return m_Type; };
	void					SetupCustom(const std::string& Name)
	{
		m_Type = ELEMENT_CUSTOM;
		m_Name = Name;

	}
	// cloning information
	BGElement*				Clone();
	static ELEMENT_TYPE		MapStringToType(const std::string& Name);
	static std::string		MapTypeToString(ELEMENT_TYPE t);
	static BGElement*		FromName(BGScene*	pScene, const std::string& Name);
protected:
	virtual	void			CopyData(BGElement*	pFrom);	

	std::string				m_Name;
	ELEMENT_TYPE			m_Type;
	BGScene*				m_pScene;
	math::Vec2				m_Pos, m_Size;
	math::Vec2				m_Dir;
	math::Vec2				m_BasePos;
	math::Vec2				m_ClipSize;
	float					m_Sort;
	float					m_Rotation;
	bool					m_IsActive;

private:
	math::Vec2				m_InitialPos, m_InitialSize;
	math::Vec2				m_InitialDir;
	math::Vec2				m_InitialBasePos;
	float					m_InitialSort;
	float					m_InitialRotation;
	bool					m_WasLoadedFromFile;
	
};

}  // namespace background

#endif // _BG_ELEMENT_H_